package com.dms.wuziqi.JwtUtil;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    // 秘钥，需要妥善保管，实际应用中建议配置在环境变量等安全的地方
    private static final String SECRET_KEY = "your_secret_key";
    // token过期时间，单位毫秒，这里设置为1小时，可以根据实际需求调整
    private static final long EXPIRATION_TIME = 3600000;

    /**
     * 创建JWT token
     *
     * @param subject 一般存放用户的标识信息，比如用户名等，会作为token的主体内容
     * @return 生成的JWT token字符串
     */
    public static String createToken(String subject) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, subject);
    }

    /**
     * 创建带有自定义声明信息的JWT token
     *
     * @param claims  自定义的声明信息，以键值对形式存放，可以添加额外想要在token中携带的信息
     * @param subject 一般存放用户的标识信息，比如用户名等，会作为token的主体内容
     * @return 生成的JWT token字符串
     */
    public static String createToken(Map<String, Object> claims, String subject) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + EXPIRATION_TIME);

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    /**
     * 从token中获取主体内容（一般是用户名等用户标识信息）
     *
     * @param token 要解析的JWT token字符串
     * @return token中的主体内容，如果解析失败返回null
     */
    public static String getSubjectFromToken(String token) {
        Claims claims = getAllClaimsFromToken(token);
        if (claims!= null) {
            return claims.getSubject();
        }
        return null;
    }

    /**
     * 解析token获取所有声明信息（包括自定义声明和标准声明）
     *
     * @param token 要解析的JWT token字符串
     * @return 解析出的Claims对象，如果解析失败返回null
     */
    private static Claims getAllClaimsFromToken(String token) {
        try {
            JwtParser jwtParser=Jwts.parser().setSigningKey(SECRET_KEY).build();
            Claims claims=jwtParser.parseClaimsJws(token).getBody();
            return claims;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 验证token是否有效
     *
     * @param token       要验证的JWT token字符串
     * @param expectedSub 期望的主体内容（比如对应的用户名），用于验证token是否是该用户的
     * @return 如果token有效且主体内容匹配返回true，否则返回false
     */
    public static boolean validateToken(String token, String expectedSub) {
        String subject = getSubjectFromToken(token);
        return subject!= null && subject.equals(expectedSub) &&!isTokenExpired(token);
    }

    /**
     * 判断token是否过期
     *
     * @param token 要判断的JWT token字符串
     * @return 如果token已过期返回true，否则返回false
     */
    private static boolean isTokenExpired(String token) {
        Claims claims = getAllClaimsFromToken(token);
        Date expiration = claims!= null? claims.getExpiration() : null;
        return expiration!= null && expiration.before(new Date());
    }
}